using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Tycho.Parser.Peg;

namespace Tycho.Parser.Tests.Peg {
    [TestFixture]
    public class ImmutableStackNodeSpecification {
        [Test]
        public void ShouldPushAndPopItem () {
            var stack = new ImmutableStackNode<object> ();

            Assert.True (stack.IsEmpty);
            var newStack = stack.Push (6);

            Assert.False (newStack.IsEmpty);

            Assert.That (newStack.Item, Is.EqualTo (6));
            Assert.That (newStack.Pop (), Is.SameAs (stack));
        }

        [Test]
        public void ShouldBeImmutable () {
            var stack = new ImmutableStackNode<object> ();
            var newStack = stack.Push (3);

            Assert.That (newStack.SequenceEqual (new object[] {3}));

            newStack.Push (5);
            Assert.That (newStack.SequenceEqual (new object[] {3}));

            newStack.Pop ();
            Assert.That (newStack.SequenceEqual (new object[] {3}));
        }

        [Test]
        public void PopShouldThrowExceptionIfEmpty () {
            var stack = new ImmutableStackNode<object> ();

            Assert.That (() => { stack.Pop (); }, Throws.TypeOf (typeof (InvalidOperationException)));
        }

        [Test]
        public void ShouldEnumerateItemsFromTopOfStack () {
            var stack = new ImmutableStackNode<object> ();
            var newStack = stack.Push (1);
            newStack = newStack.Push (2);
            newStack = newStack.Push (3);
            newStack = newStack.Push (4);

            Assert.That (newStack.SequenceEqual (new object [] {4, 3, 2, 1}));
            Assert.That (stack.SequenceEqual (new object [] {}));
        }
    }
}